const url = require("url")
const { Url } = require("url")

const db = require('../../model/index')
const utilx = require('../../lib/utilx')
const responser = require('../../lib/responser');
const helper = require("../../helper/auth")
const {Check, CheckNull} = require("../../lib/check");
const cache = require("../../instance/cache")
const pkg = require("../../package.json")
const config = require("../../config/config")

const staticPrefix = config.staticPrefix

const Model = db.models
const Students = Model.User
const User = Model.User
const Course = Model.Course
const Comment = Model.Comment
const History = Model.History

var HtmlUtil = {
    /*1.用正则表达式实现html转码*/
    htmlEncodeByRegExp:function (str){
        var s = "";
        if(str.length == 0) return "";
        s = str.replace(/&/g,"&amp;");
        s = s.replace(/</g,"&lt;");
        s = s.replace(/>/g,"&gt;");
        s = s.replace(/ /g,"&nbsp;");
        s = s.replace(/\'/g,"&#39;");
        s = s.replace(/\"/g,"&quot;");
        return s;
    },
    /*2.用正则表达式实现html解码*/
    htmlDecodeByRegExp:function (str){
        var s = "";
        if(str.length == 0) return "";
        s = str.replace(/&amp;/g,"&");
        s = s.replace(/&lt;/g,"<");
        s = s.replace(/&gt;/g,">");
        s = s.replace(/&nbsp;/g," ");
        s = s.replace(/&#39;/g,"\'");
        s = s.replace(/&quot;/g,"\"");
        return s;
    }
};

function changeUserAvatarPath(user){
    var URL = new Url()
    URL.protocol = staticPrefix.protocol
    URL.hostname = staticPrefix.hostname
    URL.port = staticPrefix.port

    URL.pathname = user.avatar
    user.avatar = url.format(URL)

    return user
}

module.exports = (router) => {
    router.get("/students/all", async (ctx) => {
        var students = await Students.findAll({
            attributes: {
                exclude: ['password']
            }
        }).map((user) => {
            return changeUserAvatarPath(user)
        })
        responser.success(ctx,students)
    })

    // with cookie
    router.get("/user/info", async (ctx) => {
        var user = await helper.user(ctx)
        if(! user){
            // HTTP 400 promise return undefined
            // Do not change to reject
            responser.success(ctx,{
                error : "cookieError"
            })
            return
        }

        responser.success(ctx,{
            username : user.username,
            avatar : changeUserAvatarPath(user).avatar,
            email : user.email,
            city : user.city,
            sign : user.sign,
            id : user.id
        })
    })

    async function getUserByLoginToken(loginToken){
        var username = await cache.get(loginToken)
        var user = await User.findOne({
            where : {
                username
            }
        })
        return user
    }

    /**
     * 笔记和评论添加
     */
    router.post("/user/comment/add", async (ctx) => {
        Check(ctx,"content",["isNote","toInt"],"LoginToken","courseId")

        var body = ctx.request.body
        var loginToken = body.LoginToken
        var content = body.content
        var isNote = body.isNote
        var courseId = body.courseId

        content = HtmlUtil.htmlEncodeByRegExp(content)

        var user = await getUserByLoginToken(loginToken)
        if(user == null || typeof user == "undefined"){
            responser.reject(ctx,{
                error : "cookieError"
            })
            return
        }

        var comment = await Comment.create({
            text : content,
            type : 1,
            isNote,
            CourseId : courseId,
            UserId : user.id
        })

        comment = await Comment.findOne({
            where : {
                id : comment.id
            },
            include : {
                model : User,
                attributes : {
                    exclude : ["password","mobile","email","createdAt","updatedAt","type"]
                }
            }
        })

        responser.success(ctx,comment)
    })

    router.post("/user/comment/star", async (ctx) => {
        Check(ctx,["commentId","toInt"],"LoginToken")

        var body = ctx.request.body
        var commentId = body.commentId
        var loginToken = body.LoginToken

        var user = await getUserByLoginToken(loginToken)
        if(user == null || typeof user == "undefined"){
            responser.reject(ctx,{
                error : "cookieError"
            })
            return
        }

        var comment = await Comment.findOne({
            where : {
                id : commentId
            }
        })
        if(!comment){
            return
        }
        await Comment.update({
            star : comment.star + 1
        },{
            where : {
                id : comment.id
            }
        })

        responser.success(ctx,comment)
    })

    router.post("/user/course/history/add", async (ctx) => {
        Check(ctx,"courseId","userId")

        var body = ctx.request.body
        var courseId = body.courseId
        var userId = body.userId

        // check courseId and userId
        var course = await Course.findById(courseId)
        var user = await User.findById(userId)
        if(! course || !user){
            responser.reject(ctx,"IdError")
            return
        }

        // create history
        var history = await History.findOne({
            where : {
                CourseId : courseId,
                UserId : userId
            }
        })
        if(! history){
            history = await History.create({
                CourseId : courseId,
                UserId : userId
            })
        }else{
            history = await History.update({
                updatedAt : new Date()
            },{
                where : {
                    CourseId : courseId,
                    UserId : userId
                }
            })
        }

        responser.success(ctx,history)
    })

    router.get("/user/history/list", async (ctx) => {
        Check(ctx,["userId","toInt"])

        var query = ctx.request.query
        var userId = query.userId

        // todo : change to query get comment number and star number
        var histories = await History.findAll({
            where : {
                UserId : userId,
                isDeleted : 0
            },
            order : [["updatedAt","DESC"]],
            include : {
                model : Course
            }
        })

        responser.success(ctx,histories)
    })

    router.post("/user/history/del", async (ctx) => {
        Check(ctx,"LoginToken",["historyId","toInt"])

        var body = ctx.request.body
        var loginToken = body.LoginToken
        var historyId = body.historyId

        var user = await getUserByLoginToken(loginToken)
        if(user == null || typeof user == "undefined"){
            responser.reject(ctx,{
                error : "cookieError"
            })
            return
        }

        await History.update({
            isDeleted : 1
        },{
            where : {
                id : historyId,
                UserId : user.id
            }
        })

        responser.success(ctx,"ok")
    })

    router.get("/user/course/collect/list", async (ctx) => {
        Check(ctx,"userId")

        var query = ctx.request.query
        var userId = query.userId

        var user = await User.findById(userId)
        if(user == null || typeof user == "undefined"){
            responser.reject(ctx,{
                error : "IdError"
            })
            return
        }

        var histories = await History.findAll({
            where : {
                UserId : userId,
                isCollect : 1
            },
            include : {
                model : Course
            }
        })

        responser.success(ctx,histories)
    })

    router.post("/user/course/collect", async (ctx) => {
        Check(ctx,"LoginToken",["historyId","toInt"])

        var body = ctx.request.body
        var loginToken = body.LoginToken
        var historyId = body.historyId

        var user = await getUserByLoginToken(loginToken)
        if(user == null || typeof user == "undefined"){
            responser.reject(ctx,{
                error : "cookieError"
            })
            return
        }

        var history = await History.findOne({
            where : {
                id : historyId,
                UserId : user.id
            }
        })
        if(!history){
            return
        }

        await History.update({
            isCollect : (history.isCollect + 1) % 2
        },{
            where : {
                id : history.id
            }
        })

        responser.success(ctx,"ok")
    })

    router.post("/user/update/avatar",async (ctx) => {
        Check(ctx,"avatar","LoginToken")

        var body = ctx.request.body
        var avatar = body.avatar
        var loginToken = body.LoginToken

        var user = await getUserByLoginToken(loginToken)
        if(! user){
            responser.reject(ctx,"token is invalid",403)
            return
        }

        await User.update({
            avatar : body.avatar
        },{
            where : {
                id : user.id
            }
        })

        user.avatar = body.avatar
        changeUserAvatarPath(user)
        responser.success(ctx,user.avatar)

    })
}